/*
*	Project: Aethon
*
*	File: Terrain.cpp
*
*	Author: Caleb Reinking
*
*	Date: 2/15/2009
*
*   Purpose: The Terrain class builds the terrain using a heightmap file and 
*            bitmap texture. The heightmap file format is found at the bottom of
*            this specification file. It consists of a dimension, separation
*            factor, and the heights at every (x,z) point on the surface. The 
*            heights can never be negative. 
*            Terrain Class Implementation File
*/

#include "../include/Terrain.h"
#include "../include/CollisionSphere.h"
#include <fstream>
#include <iostream>

using namespace std;


// UNUSED	
//##########################################################################
	int Terrain::collidesWith( CollisionSphere sphere )
	{
	   cout << "Check to see if the sphere collides with a certain face "
	        << "of the terrain" << endl;
		return 0;
	} // end collidesWith
	
	
//##########################################################################
// Loads the terrain into an OpenGL display list for future display calls
int Terrain::load( string heightFileName, string texFileName )
{
    ifstream inputFile;
    string inputFileName = "../data/maps/" + heightFileName + ".txt";
    modPart.processImage( texFileName );    
    
    inputFile.open( inputFileName.c_str() );
    if( !inputFile )
    {
        fprintf(stderr, "Error Loading Terrain File: terrain.load() \n" );
        exit(0);
    }
    
    //Terrain file specification found in Terrain.h
    inputFile >> dimension;
    inputFile >> separationFact;
    
    
    // Loads all of the heights at the respective x,z positions
    string temp;
    for( int x = 0; x < dimension ; x++ )
    {
    	 for( int z = 0; z < dimension ; z++ )
    	 {
    		  inputFile >> temp;
    		  heightGrid[x][z] = atof(temp.c_str())/10.0;  		  
    	 }
    }	
    inputFile.close();
    	
   terrainId = glGenLists(1);
   glNewList( terrainId, GL_COMPILE );
       // begin the actual openGL displaying of the terrain 
       modPart.loadTexture();
       
       float f_dim = dimension/1.0; // to avoid integer division
       
       glPushMatrix();
       
       glColor3ub( 255, 255, 255 ); // creates white quads until the texture is applied
       
       // algorithm to draw all of the squares using the heightgrid array.
       // Be careful when modifying this because it is easy to go out of bounds on
       // the arrays.
       glBegin(GL_QUADS);
    	   for( int i = dimension-1 ; i > 0 ; i-- )
    	   {
    		  for( int j = 0 ; j < dimension-1 ; j++ )
    		  {
    			 glTexCoord2d( (i)/f_dim,(j+1)/f_dim);  
    			 glVertex3f(i*separationFact, heightGrid[i][j], j*separationFact );
    			 
    			 glTexCoord2d( (i-1)/f_dim,(j+1)/f_dim); 
    			 glVertex3f((i)*separationFact, heightGrid[i][j+1], (j+1)*separationFact );
    			 
    			 glTexCoord2d( (i-1)/f_dim,(j)/f_dim); 
    			 glVertex3f((i-1)*separationFact, heightGrid[i-1][j+1], (j+1)*separationFact );
    			 
    			 glTexCoord2d(i/f_dim ,j/f_dim); 
    			 glVertex3f((i-1)*separationFact, heightGrid[i-1][j], (j)*separationFact );
    		  }
    		}
    	glEnd();
    	
    	
    	glPopMatrix();
	glEndList();
    
    return 0;
    
} // end load
	
//##########################################################################
void Terrain::display()
{
   // Draws the terrain to the screen by calling the terrain display list created
   // in Terrain::load
   glCallList(terrainId);
      
} // end display
	
